@seed-hypermedia/client 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-link.d.ts +61 -0
- package/dist/block-diff.d.ts +62 -0
- package/dist/blocks-to-markdown.d.ts +33 -0
- package/dist/change.d.ts +7 -0
- package/dist/{chunk-YUKHBJYL.mjs → chunk-X57BIZUK.mjs} +256 -8
- package/dist/client.d.ts +1 -1
- package/dist/comment.d.ts +5 -0
- package/dist/contact.d.ts +16 -2
- package/dist/document-state.d.ts +23 -0
- package/dist/file-to-ipfs.d.ts +53 -0
- package/dist/grobid.d.ts +22 -0
- package/dist/hm-types.d.ts +3220 -352
- package/dist/hm-types.mjs +47 -1
- package/dist/index.d.ts +33 -13
- package/dist/index.mjs +2378 -64
- package/dist/markdown-to-blocks.d.ts +88 -0
- package/dist/pdf-to-blocks-embedded.d.ts +23 -0
- package/dist/pdf-to-blocks.d.ts +55 -0
- package/dist/ref.d.ts +2 -0
- package/dist/tei-to-blocks.d.ts +52 -0
- package/package.json +45 -17
- package/src/index.ts +74 -0
- package/LICENSE +0 -201
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-link child documents to their parent on first publish.
|
|
3
|
+
*
|
|
4
|
+
* When a document is created at a nested path (e.g. /docs/my-article), the
|
|
5
|
+
* parent document at /docs should contain an embed link pointing to the child.
|
|
6
|
+
* This module provides:
|
|
7
|
+
*
|
|
8
|
+
* - Pure decision logic: should a link be added?
|
|
9
|
+
* - Operation builder: what DocumentOperations to emit
|
|
10
|
+
* - Full I/O convenience: fetch parent, check, build ops, sign, publish
|
|
11
|
+
*/
|
|
12
|
+
import type { HMDocument, HMSigner, UnpackedHypermediaId } from './hm-types';
|
|
13
|
+
import type { SeedClient } from './client';
|
|
14
|
+
import type { DocumentOperation } from './change';
|
|
15
|
+
/**
|
|
16
|
+
* Check if a document contains a link/embed to a specific child document.
|
|
17
|
+
* Compares URLs ignoring version and latest flags.
|
|
18
|
+
*/
|
|
19
|
+
export declare function documentContainsLinkToChild(document: HMDocument, childId: UnpackedHypermediaId): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Check if a document has a self-referential Query block
|
|
22
|
+
* (a query to itself that would automatically include children).
|
|
23
|
+
*/
|
|
24
|
+
export declare function documentHasSelfQuery(document: HMDocument, documentId: UnpackedHypermediaId): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Determine whether a parent auto-link should be added on first publish.
|
|
27
|
+
* Returns true when the parent document should receive an embed link to the child.
|
|
28
|
+
*/
|
|
29
|
+
export declare function shouldAutoLinkParent(isPrivate: boolean, parentDocument: HMDocument | null, editableLocation: UnpackedHypermediaId, parentId: UnpackedHypermediaId): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Generate the DocumentOperations to append an Embed Card block to a parent document.
|
|
32
|
+
*
|
|
33
|
+
* The returned operations include a ReplaceBlock for the new embed block and a
|
|
34
|
+
* MoveBlocks that lists ALL root-level block IDs (existing + new) to ensure
|
|
35
|
+
* correct ordering. The CBOR MoveBlocks format with no `ref` positions blocks
|
|
36
|
+
* from the start, so we must re-specify the full ordering.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createAutoLinkOps(parentDocument: HMDocument, childHmUrl: string, newBlockId: string): DocumentOperation[];
|
|
39
|
+
/** Options for the auto-link convenience function. */
|
|
40
|
+
export type AutoLinkChildToParentOptions = {
|
|
41
|
+
/** Seed API client. */
|
|
42
|
+
client: SeedClient;
|
|
43
|
+
/** Account UID of the document owner. */
|
|
44
|
+
account: string;
|
|
45
|
+
/** Full path of the child document (e.g. "/tests/benefits-of-cli"). */
|
|
46
|
+
path: string;
|
|
47
|
+
/** hm:// URL of the published child document (with version). */
|
|
48
|
+
childHmUrl: string;
|
|
49
|
+
/** Signer for the parent document change. */
|
|
50
|
+
signer: HMSigner;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Auto-link a newly published child document to its parent.
|
|
54
|
+
*
|
|
55
|
+
* Computes the parent path, fetches the parent document, decides whether a link
|
|
56
|
+
* is needed (using `shouldAutoLinkParent`), and if so publishes an Embed Card
|
|
57
|
+
* block to the parent document.
|
|
58
|
+
*
|
|
59
|
+
* Returns true if a link was added, false otherwise. Throws on network errors.
|
|
60
|
+
*/
|
|
61
|
+
export declare function autoLinkChildToParent(opts: AutoLinkChildToParentOptions): Promise<boolean>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block diffing utilities for document update.
|
|
3
|
+
*
|
|
4
|
+
* Computes minimal document operations by comparing existing document
|
|
5
|
+
* blocks with new blocks parsed from Markdown or JSON input.
|
|
6
|
+
*
|
|
7
|
+
* The primary flow trusts block IDs from the input: if an input block's
|
|
8
|
+
* ID exists in the old document, it's treated as an existing block and
|
|
9
|
+
* diffed for content changes. If the ID doesn't exist, the block is
|
|
10
|
+
* treated as new. Old blocks whose IDs don't appear in the new tree
|
|
11
|
+
* are deleted. This gives per-block granularity — a mix of known and
|
|
12
|
+
* unknown IDs is handled correctly.
|
|
13
|
+
*/
|
|
14
|
+
import type { DocumentOperation } from './change';
|
|
15
|
+
import type { HMBlockNode } from './hm-types';
|
|
16
|
+
import type { BlockNode } from './markdown-to-blocks';
|
|
17
|
+
export type APIBlockNode = {
|
|
18
|
+
block: APIBlock;
|
|
19
|
+
children: APIBlockNode[];
|
|
20
|
+
};
|
|
21
|
+
export type APIBlock = {
|
|
22
|
+
id: string;
|
|
23
|
+
type: string;
|
|
24
|
+
text: string;
|
|
25
|
+
link: string;
|
|
26
|
+
annotations: unknown[];
|
|
27
|
+
attributes: Record<string, unknown>;
|
|
28
|
+
revision?: string;
|
|
29
|
+
};
|
|
30
|
+
type BlocksMapItem = {
|
|
31
|
+
parent: string;
|
|
32
|
+
left: string;
|
|
33
|
+
block: APIBlock;
|
|
34
|
+
};
|
|
35
|
+
type BlocksMap = Record<string, BlocksMapItem>;
|
|
36
|
+
export declare function createBlocksMap(nodes: APIBlockNode[], parentId?: string): BlocksMap;
|
|
37
|
+
/**
|
|
38
|
+
* Walk old and new block trees in parallel. When the new block at
|
|
39
|
+
* position N has the same type as the old block at position N, reuse
|
|
40
|
+
* the old block's ID. Otherwise assign the new block's generated ID.
|
|
41
|
+
*
|
|
42
|
+
* Returns a new tree with IDs reassigned (does not mutate inputs).
|
|
43
|
+
*/
|
|
44
|
+
export declare function matchBlockIds(oldNodes: APIBlockNode[], newNodes: BlockNode[]): BlockNode[];
|
|
45
|
+
/**
|
|
46
|
+
* Compare the new block tree against the old blocks map and produce
|
|
47
|
+
* the minimal set of DocumentOperations:
|
|
48
|
+
*
|
|
49
|
+
* - ReplaceBlock for new or content-changed blocks
|
|
50
|
+
* - MoveBlocks for positioning (new blocks or position changes)
|
|
51
|
+
* - DeleteBlocks for blocks removed from the document
|
|
52
|
+
*/
|
|
53
|
+
export declare function computeReplaceOps(oldMap: BlocksMap, matchedTree: BlockNode[], parentId?: string): DocumentOperation[];
|
|
54
|
+
/**
|
|
55
|
+
* Convert an HMBlockNode tree (from JSON input or API response) into
|
|
56
|
+
* a BlockNode tree compatible with the diff pipeline.
|
|
57
|
+
*
|
|
58
|
+
* HMBlockNode nests childrenType/language inside `attributes`, while
|
|
59
|
+
* SeedBlock/BlockNode has them at the top level.
|
|
60
|
+
*/
|
|
61
|
+
export declare function hmBlockNodeToBlockNode(node: HMBlockNode): BlockNode;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seed block tree → Markdown formatter.
|
|
3
|
+
*
|
|
4
|
+
* Converts HMDocument/HMBlockNode trees to markdown with:
|
|
5
|
+
* - YAML frontmatter (always emitted, all HMMetadata fields)
|
|
6
|
+
* - Block IDs preserved as HTML comments (<!-- id:XXXXXXXX -->)
|
|
7
|
+
* - Inline annotations rendered as markdown formatting
|
|
8
|
+
*
|
|
9
|
+
* This module is purely synchronous and does NOT resolve embeds, mentions,
|
|
10
|
+
* or queries over the network. For resolved output, use the CLI's wrapper
|
|
11
|
+
* which adds a SeedClient-backed resolve layer on top.
|
|
12
|
+
*
|
|
13
|
+
* Round-trip compatible: output can be piped back through `parseMarkdown()`
|
|
14
|
+
* to recreate the same document with block IDs preserved.
|
|
15
|
+
*/
|
|
16
|
+
import type { HMDocument, HMMetadata } from './hm-types';
|
|
17
|
+
export type BlocksToMarkdownOptions = {
|
|
18
|
+
/** Format ipfs:// URLs as https gateway URLs. Default: true. */
|
|
19
|
+
ipfsGateway?: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Emit YAML frontmatter from HMMetadata.
|
|
23
|
+
* Only includes fields that have defined, non-empty values.
|
|
24
|
+
* System fields (authors, version, genesis, account) are NOT emitted.
|
|
25
|
+
*/
|
|
26
|
+
export declare function emitFrontmatter(metadata: HMMetadata): string;
|
|
27
|
+
/**
|
|
28
|
+
* Convert an HMDocument to markdown with frontmatter and block IDs.
|
|
29
|
+
*
|
|
30
|
+
* This is a synchronous, pure conversion. Embeds/queries are rendered
|
|
31
|
+
* as placeholder links (not resolved).
|
|
32
|
+
*/
|
|
33
|
+
export declare function blocksToMarkdown(doc: HMDocument, options?: BlocksToMarkdownOptions): string;
|
package/dist/change.d.ts
CHANGED
|
@@ -103,6 +103,11 @@ export declare function createDocumentChange(input: CreateDocumentChangeInput, s
|
|
|
103
103
|
bytes: Uint8Array;
|
|
104
104
|
cid: CID;
|
|
105
105
|
}>;
|
|
106
|
+
/**
|
|
107
|
+
* Map a proto ResourceVisibility enum value to the CBOR string used in Ref blobs.
|
|
108
|
+
* Returns "Private" for private documents, undefined otherwise (omitted from CBOR = public).
|
|
109
|
+
*/
|
|
110
|
+
export declare function visibilityToCbor(protoVisibility?: number): string | undefined;
|
|
106
111
|
export type SignDocumentChangeInput = {
|
|
107
112
|
/** Account UID (base58btc-encoded principal) */
|
|
108
113
|
account: string;
|
|
@@ -116,6 +121,8 @@ export type SignDocumentChangeInput = {
|
|
|
116
121
|
generation?: number | bigint;
|
|
117
122
|
/** Optional capability CID string */
|
|
118
123
|
capability?: string;
|
|
124
|
+
/** Proto ResourceVisibility enum value (0=unspecified, 1=public, 2=private) */
|
|
125
|
+
visibility?: number;
|
|
119
126
|
};
|
|
120
127
|
/**
|
|
121
128
|
* Sign a prepared change and create a version ref, returning blobs ready for publishing.
|
|
@@ -21,7 +21,7 @@ var unpackedHmIdSchema = z.object({
|
|
|
21
21
|
targetDocUid: z.string().nullable().optional(),
|
|
22
22
|
targetDocPath: z.array(z.string()).nullable().optional()
|
|
23
23
|
});
|
|
24
|
-
var HMBlockChildrenTypeSchema = z.union([z.literal("Group"), z.literal("Ordered"), z.literal("Unordered"), z.literal("Blockquote")]).nullable();
|
|
24
|
+
var HMBlockChildrenTypeSchema = z.union([z.literal("Group"), z.literal("Ordered"), z.literal("Unordered"), z.literal("Blockquote"), z.literal("Grid")]).nullable();
|
|
25
25
|
var HMEmbedViewSchema = z.union([z.literal("Content"), z.literal("Card"), z.literal("Comments")]);
|
|
26
26
|
var HMQueryStyleSchema = z.union([z.literal("Card"), z.literal("List")]);
|
|
27
27
|
var baseAnnotationProperties = {
|
|
@@ -93,7 +93,8 @@ var textBlockProperties = {
|
|
|
93
93
|
annotations: HMAnnotationsSchema
|
|
94
94
|
};
|
|
95
95
|
var parentBlockAttributes = {
|
|
96
|
-
childrenType: HMBlockChildrenTypeSchema.optional()
|
|
96
|
+
childrenType: HMBlockChildrenTypeSchema.optional(),
|
|
97
|
+
columnCount: z.number().optional()
|
|
97
98
|
};
|
|
98
99
|
var HMBlockParagraphSchema = z.object({
|
|
99
100
|
type: z.literal("Paragraph"),
|
|
@@ -221,6 +222,7 @@ var HMDocumentMetadataSchema = z.object({
|
|
|
221
222
|
siteUrl: z.string().optional(),
|
|
222
223
|
layout: z.union([z.literal("Seed/Experimental/Newspaper"), z.literal("")]).optional(),
|
|
223
224
|
displayPublishTime: z.string().optional(),
|
|
225
|
+
displayAuthor: z.string().optional(),
|
|
224
226
|
seedExperimentalLogo: z.string().optional(),
|
|
225
227
|
seedExperimentalHomeOrder: z.union([z.literal("UpdatedFirst"), z.literal("CreatedFirst")]).optional(),
|
|
226
228
|
showOutline: z.boolean().optional(),
|
|
@@ -339,6 +341,10 @@ var HMAccountNotFoundSchema = z.object({
|
|
|
339
341
|
uid: z.string()
|
|
340
342
|
});
|
|
341
343
|
var HMAccountResultSchema = z.discriminatedUnion("type", [HMAccountPayloadSchema, HMAccountNotFoundSchema]);
|
|
344
|
+
var HMSiteMemberSchema = z.object({
|
|
345
|
+
account: unpackedHmIdSchema,
|
|
346
|
+
role: z.enum(["owner", "writer", "member"])
|
|
347
|
+
});
|
|
342
348
|
var HMAccountsMetadataSchema = z.record(
|
|
343
349
|
z.string(),
|
|
344
350
|
// account uid
|
|
@@ -356,7 +362,8 @@ var HMQuerySortSchema = z.object({
|
|
|
356
362
|
z.literal("Title"),
|
|
357
363
|
z.literal("CreateTime"),
|
|
358
364
|
z.literal("UpdateTime"),
|
|
359
|
-
z.literal("DisplayTime")
|
|
365
|
+
z.literal("DisplayTime"),
|
|
366
|
+
z.literal("ActivityTime")
|
|
360
367
|
])
|
|
361
368
|
});
|
|
362
369
|
var HMQuerySchema = z.object({
|
|
@@ -475,13 +482,19 @@ var HMResolvedResourceSchema = z.discriminatedUnion("type", [
|
|
|
475
482
|
HMResourceCommentSchema,
|
|
476
483
|
HMResourceTombstoneSchema
|
|
477
484
|
]);
|
|
485
|
+
var HMContactSubscribeSchema = z.object({
|
|
486
|
+
site: z.boolean().optional(),
|
|
487
|
+
profile: z.boolean().optional()
|
|
488
|
+
});
|
|
478
489
|
var HMContactRecordSchema = z.object({
|
|
479
490
|
id: z.string(),
|
|
480
491
|
subject: z.string(),
|
|
481
492
|
name: z.string(),
|
|
482
493
|
account: z.string(),
|
|
494
|
+
signer: z.string(),
|
|
483
495
|
createTime: HMTimestampSchema.optional(),
|
|
484
|
-
updateTime: HMTimestampSchema.optional()
|
|
496
|
+
updateTime: HMTimestampSchema.optional(),
|
|
497
|
+
subscribe: HMContactSubscribeSchema.optional()
|
|
485
498
|
});
|
|
486
499
|
var HMAccountContactsRequestSchema = z.object({
|
|
487
500
|
key: z.literal("AccountContacts"),
|
|
@@ -489,6 +502,122 @@ var HMAccountContactsRequestSchema = z.object({
|
|
|
489
502
|
// account UID
|
|
490
503
|
output: z.array(HMContactRecordSchema)
|
|
491
504
|
});
|
|
505
|
+
var HMCommentDraftSchema = z.object({
|
|
506
|
+
blocks: z.array(HMBlockNodeSchema),
|
|
507
|
+
targetDocId: z.string().optional(),
|
|
508
|
+
replyCommentId: z.string().optional(),
|
|
509
|
+
quotingBlockId: z.string().optional(),
|
|
510
|
+
context: z.enum(["accessory", "feed", "document-content"]).optional(),
|
|
511
|
+
lastUpdateTime: z.number().optional()
|
|
512
|
+
});
|
|
513
|
+
var HMListedCommentDraftSchema = z.object({
|
|
514
|
+
id: z.string(),
|
|
515
|
+
targetDocId: z.string(),
|
|
516
|
+
replyCommentId: z.string().optional(),
|
|
517
|
+
quotingBlockId: z.string().optional(),
|
|
518
|
+
context: z.enum(["accessory", "feed", "document-content"]).optional(),
|
|
519
|
+
lastUpdateTime: z.number()
|
|
520
|
+
});
|
|
521
|
+
var HMHostConfigSchema = z.object({
|
|
522
|
+
peerId: z.string(),
|
|
523
|
+
registeredAccountUid: z.string(),
|
|
524
|
+
protocolId: z.string(),
|
|
525
|
+
addrs: z.array(z.string()),
|
|
526
|
+
hostname: z.string(),
|
|
527
|
+
isGateway: z.boolean()
|
|
528
|
+
});
|
|
529
|
+
var HMContactSchema = z.object({
|
|
530
|
+
metadata: HMDocumentMetadataSchema,
|
|
531
|
+
contacts: z.array(HMContactRecordSchema).optional(),
|
|
532
|
+
subjectContacts: z.array(HMContactRecordSchema).optional()
|
|
533
|
+
});
|
|
534
|
+
var HMContactItemSchema = z.object({
|
|
535
|
+
id: unpackedHmIdSchema,
|
|
536
|
+
metadata: HMDocumentMetadataSchema.optional()
|
|
537
|
+
});
|
|
538
|
+
var HMCapabilitySchema = z.object({
|
|
539
|
+
id: z.string(),
|
|
540
|
+
accountUid: z.string(),
|
|
541
|
+
role: HMRoleSchema,
|
|
542
|
+
capabilityId: z.string().optional(),
|
|
543
|
+
grantId: unpackedHmIdSchema,
|
|
544
|
+
label: z.string().optional(),
|
|
545
|
+
createTime: HMTimestampSchema
|
|
546
|
+
});
|
|
547
|
+
var siteDiscoverRequestSchema = z.object({
|
|
548
|
+
uid: z.string(),
|
|
549
|
+
path: z.array(z.string()),
|
|
550
|
+
version: z.string().optional(),
|
|
551
|
+
media: z.boolean().optional()
|
|
552
|
+
});
|
|
553
|
+
var HMPeerConnectionRequestSchema = z.object({
|
|
554
|
+
a: z.array(z.string()),
|
|
555
|
+
// addrs
|
|
556
|
+
d: z.string()
|
|
557
|
+
// peer/device ID
|
|
558
|
+
});
|
|
559
|
+
var ParsedFragmentSchema = BlockRangeSchema.extend({
|
|
560
|
+
blockId: z.string()
|
|
561
|
+
});
|
|
562
|
+
var HMCitationCommentSourceSchema = z.object({
|
|
563
|
+
type: z.literal("c"),
|
|
564
|
+
id: unpackedHmIdSchema,
|
|
565
|
+
author: z.string().optional(),
|
|
566
|
+
time: HMTimestampSchema.optional()
|
|
567
|
+
});
|
|
568
|
+
var HMCitationDocumentSourceSchema = z.object({
|
|
569
|
+
type: z.literal("d"),
|
|
570
|
+
id: unpackedHmIdSchema,
|
|
571
|
+
author: z.string().optional(),
|
|
572
|
+
time: HMTimestampSchema.optional()
|
|
573
|
+
});
|
|
574
|
+
var HMCitationSchema = z.object({
|
|
575
|
+
source: z.discriminatedUnion("type", [HMCitationCommentSourceSchema, HMCitationDocumentSourceSchema]),
|
|
576
|
+
isExactVersion: z.boolean(),
|
|
577
|
+
targetFragment: ParsedFragmentSchema.nullable(),
|
|
578
|
+
targetId: unpackedHmIdSchema
|
|
579
|
+
});
|
|
580
|
+
var DeviceLinkSessionSchema = z.object({
|
|
581
|
+
accountId: z.string(),
|
|
582
|
+
secretToken: z.string(),
|
|
583
|
+
addrInfo: z.object({
|
|
584
|
+
peerId: z.string(),
|
|
585
|
+
addrs: z.array(z.string())
|
|
586
|
+
})
|
|
587
|
+
});
|
|
588
|
+
var HMNavigationItemSchema = z.object({
|
|
589
|
+
type: z.literal("Link"),
|
|
590
|
+
id: z.string(),
|
|
591
|
+
text: z.string(),
|
|
592
|
+
link: z.string()
|
|
593
|
+
});
|
|
594
|
+
var HMDraftContentSchema = z.object({
|
|
595
|
+
content: z.array(z.any()),
|
|
596
|
+
// EditorBlock validation is handled elsewhere
|
|
597
|
+
deps: z.array(z.string().min(1)).default([]),
|
|
598
|
+
navigation: z.array(HMNavigationItemSchema).optional()
|
|
599
|
+
});
|
|
600
|
+
var HMDraftMetaBaseSchema = z.object({
|
|
601
|
+
id: z.string(),
|
|
602
|
+
locationUid: z.string().optional(),
|
|
603
|
+
locationPath: z.array(z.string()).optional(),
|
|
604
|
+
editUid: z.string().optional(),
|
|
605
|
+
editPath: z.array(z.string()).optional(),
|
|
606
|
+
metadata: HMDocumentMetadataSchema,
|
|
607
|
+
visibility: HMResourceVisibilitySchema.optional().default("PUBLIC")
|
|
608
|
+
});
|
|
609
|
+
var draftLocationRefinement = (data) => data.editUid || data.locationUid;
|
|
610
|
+
var HMDraftMetaSchema = HMDraftMetaBaseSchema.refine(draftLocationRefinement, {
|
|
611
|
+
message: "Either editUid or locationUid must be provided"
|
|
612
|
+
});
|
|
613
|
+
var HMListedDraftSchema = HMDraftMetaBaseSchema.extend({
|
|
614
|
+
lastUpdateTime: z.number()
|
|
615
|
+
}).refine(draftLocationRefinement, {
|
|
616
|
+
message: "Either editUid or locationUid must be provided"
|
|
617
|
+
});
|
|
618
|
+
var HMListedDraftReadSchema = HMDraftMetaBaseSchema.extend({
|
|
619
|
+
lastUpdateTime: z.number()
|
|
620
|
+
});
|
|
492
621
|
var HMSubjectContactsRequestSchema = z.object({
|
|
493
622
|
key: z.literal("SubjectContacts"),
|
|
494
623
|
input: z.string(),
|
|
@@ -521,7 +650,8 @@ var HMSearchInputSchema = z.object({
|
|
|
521
650
|
includeBody: z.boolean().optional(),
|
|
522
651
|
contextSize: z.number().optional(),
|
|
523
652
|
perspectiveAccountUid: z.string().optional(),
|
|
524
|
-
searchType: z.number().optional()
|
|
653
|
+
searchType: z.number().optional(),
|
|
654
|
+
pageSize: z.number().optional()
|
|
525
655
|
});
|
|
526
656
|
var HMSearchResultItemSchema = z.object({
|
|
527
657
|
id: unpackedHmIdSchema,
|
|
@@ -529,7 +659,7 @@ var HMSearchResultItemSchema = z.object({
|
|
|
529
659
|
title: z.string(),
|
|
530
660
|
icon: z.string(),
|
|
531
661
|
parentNames: z.array(z.string()),
|
|
532
|
-
versionTime: z.
|
|
662
|
+
versionTime: z.string().optional(),
|
|
533
663
|
searchQuery: z.string(),
|
|
534
664
|
type: z.enum(["document", "contact"])
|
|
535
665
|
});
|
|
@@ -706,6 +836,7 @@ var HMInteractionSummaryOutputSchema = z.object({
|
|
|
706
836
|
comments: z.number(),
|
|
707
837
|
changes: z.number(),
|
|
708
838
|
children: z.number(),
|
|
839
|
+
authorUids: z.array(z.string()).default([]),
|
|
709
840
|
blocks: z.record(
|
|
710
841
|
z.string(),
|
|
711
842
|
z.object({
|
|
@@ -872,7 +1003,7 @@ function getHMQueryString({
|
|
|
872
1003
|
if (version) {
|
|
873
1004
|
query.v = version;
|
|
874
1005
|
}
|
|
875
|
-
if (latest) {
|
|
1006
|
+
if (latest && version) {
|
|
876
1007
|
query.l = null;
|
|
877
1008
|
}
|
|
878
1009
|
if (panel) {
|
|
@@ -905,6 +1036,100 @@ function entityQueryPathToHmIdPath(path) {
|
|
|
905
1036
|
if (path === "/") return [];
|
|
906
1037
|
return path.split("/").filter(Boolean);
|
|
907
1038
|
}
|
|
1039
|
+
function parseCustomURL(url) {
|
|
1040
|
+
if (!url) return null;
|
|
1041
|
+
const [scheme, rest] = url.split("://");
|
|
1042
|
+
if (!rest) return null;
|
|
1043
|
+
const [pathAndQuery, fragment = null] = rest.split("#");
|
|
1044
|
+
const [path, queryString] = (pathAndQuery == null ? void 0 : pathAndQuery.split("?")) || [];
|
|
1045
|
+
const query = new URLSearchParams(queryString);
|
|
1046
|
+
const queryObject = Object.fromEntries(query.entries());
|
|
1047
|
+
return {
|
|
1048
|
+
scheme: scheme || null,
|
|
1049
|
+
path: (path == null ? void 0 : path.split("/")) || [],
|
|
1050
|
+
query: queryObject,
|
|
1051
|
+
fragment
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
function parseFragment(input) {
|
|
1055
|
+
if (!input) return null;
|
|
1056
|
+
const regex = /^([^\+\[]+)((\+)|\[(\d+)\:(\d+)\])?$/;
|
|
1057
|
+
const match = input.match(regex);
|
|
1058
|
+
if (match) {
|
|
1059
|
+
const blockId = match[1] || "";
|
|
1060
|
+
const expanded = match[3];
|
|
1061
|
+
const rangeStart = match[4];
|
|
1062
|
+
const rangeEnd = match[5];
|
|
1063
|
+
if (expanded === "+") {
|
|
1064
|
+
return { blockId, expanded: true };
|
|
1065
|
+
} else if (typeof rangeStart !== "undefined" && typeof rangeEnd !== "undefined") {
|
|
1066
|
+
return { blockId, start: parseInt(rangeStart), end: parseInt(rangeEnd) };
|
|
1067
|
+
} else {
|
|
1068
|
+
return { blockId, expanded: false };
|
|
1069
|
+
}
|
|
1070
|
+
} else {
|
|
1071
|
+
return { blockId: input, expanded: false };
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
var STATIC_HM_PATHS = /* @__PURE__ */ new Set(["download", "connect", "register", "device-link", "profile", "contact"]);
|
|
1075
|
+
function unpackHmId(hypermediaId) {
|
|
1076
|
+
if (!hypermediaId) return null;
|
|
1077
|
+
const parsed = parseCustomURL(hypermediaId);
|
|
1078
|
+
if (!parsed) return null;
|
|
1079
|
+
let uid;
|
|
1080
|
+
let path;
|
|
1081
|
+
let hostname = null;
|
|
1082
|
+
if (parsed.scheme === "https" || parsed.scheme === "http") {
|
|
1083
|
+
if (parsed.path[1] !== "hm") return null;
|
|
1084
|
+
hostname = parsed.path[0];
|
|
1085
|
+
uid = parsed.path[2];
|
|
1086
|
+
if (uid && STATIC_HM_PATHS.has(uid)) return null;
|
|
1087
|
+
path = parsed.path.slice(3);
|
|
1088
|
+
} else if (parsed.scheme === HYPERMEDIA_SCHEME || parsed.scheme === "hm") {
|
|
1089
|
+
uid = parsed.path[0];
|
|
1090
|
+
path = parsed.path.slice(1);
|
|
1091
|
+
} else {
|
|
1092
|
+
return null;
|
|
1093
|
+
}
|
|
1094
|
+
const version = parsed.query.v || null;
|
|
1095
|
+
const fragment = parseFragment(parsed.fragment);
|
|
1096
|
+
const hasBlockRef = !!(fragment == null ? void 0 : fragment.blockId);
|
|
1097
|
+
const latest = hasBlockRef ? false : parsed.query.l === null || parsed.query.l === "" || !version;
|
|
1098
|
+
let blockRange = null;
|
|
1099
|
+
if (fragment) {
|
|
1100
|
+
if ("start" in fragment) {
|
|
1101
|
+
blockRange = { start: fragment.start, end: fragment.end };
|
|
1102
|
+
} else if ("expanded" in fragment) {
|
|
1103
|
+
blockRange = { expanded: fragment.expanded };
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
return {
|
|
1107
|
+
id: packBaseId(uid || "", path),
|
|
1108
|
+
uid: uid || "",
|
|
1109
|
+
path: path || null,
|
|
1110
|
+
version,
|
|
1111
|
+
blockRef: fragment ? fragment.blockId : null,
|
|
1112
|
+
blockRange,
|
|
1113
|
+
hostname: hostname || null,
|
|
1114
|
+
latest,
|
|
1115
|
+
scheme: parsed.scheme
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
1118
|
+
function codePointLength(entry) {
|
|
1119
|
+
let count = 0;
|
|
1120
|
+
if (!entry) return 0;
|
|
1121
|
+
for (let i = 0; i < entry.length; i++) {
|
|
1122
|
+
count++;
|
|
1123
|
+
if (isSurrogate(entry, i)) {
|
|
1124
|
+
i++;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
return count;
|
|
1128
|
+
}
|
|
1129
|
+
function isSurrogate(s, i) {
|
|
1130
|
+
const code = s.charCodeAt(i);
|
|
1131
|
+
return 55296 <= code && code <= 56319;
|
|
1132
|
+
}
|
|
908
1133
|
|
|
909
1134
|
export {
|
|
910
1135
|
BlockRangeSchema,
|
|
@@ -954,6 +1179,7 @@ export {
|
|
|
954
1179
|
HMAccountPayloadSchema,
|
|
955
1180
|
HMAccountNotFoundSchema,
|
|
956
1181
|
HMAccountResultSchema,
|
|
1182
|
+
HMSiteMemberSchema,
|
|
957
1183
|
HMAccountsMetadataSchema,
|
|
958
1184
|
HMQueryInclusionSchema,
|
|
959
1185
|
HMQuerySortSchema,
|
|
@@ -975,8 +1201,25 @@ export {
|
|
|
975
1201
|
HMResourceErrorSchema,
|
|
976
1202
|
HMResourceSchema,
|
|
977
1203
|
HMResolvedResourceSchema,
|
|
1204
|
+
HMContactSubscribeSchema,
|
|
978
1205
|
HMContactRecordSchema,
|
|
979
1206
|
HMAccountContactsRequestSchema,
|
|
1207
|
+
HMCommentDraftSchema,
|
|
1208
|
+
HMListedCommentDraftSchema,
|
|
1209
|
+
HMHostConfigSchema,
|
|
1210
|
+
HMContactSchema,
|
|
1211
|
+
HMContactItemSchema,
|
|
1212
|
+
HMCapabilitySchema,
|
|
1213
|
+
siteDiscoverRequestSchema,
|
|
1214
|
+
HMPeerConnectionRequestSchema,
|
|
1215
|
+
ParsedFragmentSchema,
|
|
1216
|
+
HMCitationSchema,
|
|
1217
|
+
DeviceLinkSessionSchema,
|
|
1218
|
+
HMNavigationItemSchema,
|
|
1219
|
+
HMDraftContentSchema,
|
|
1220
|
+
HMDraftMetaSchema,
|
|
1221
|
+
HMListedDraftSchema,
|
|
1222
|
+
HMListedDraftReadSchema,
|
|
980
1223
|
HMSubjectContactsRequestSchema,
|
|
981
1224
|
HMResourceRequestSchema,
|
|
982
1225
|
HMResourceMetadataRequestSchema,
|
|
@@ -1040,5 +1283,10 @@ export {
|
|
|
1040
1283
|
getHMQueryString,
|
|
1041
1284
|
serializeBlockRange,
|
|
1042
1285
|
hmIdPathToEntityQueryPath,
|
|
1043
|
-
entityQueryPathToHmIdPath
|
|
1286
|
+
entityQueryPathToHmIdPath,
|
|
1287
|
+
parseCustomURL,
|
|
1288
|
+
parseFragment,
|
|
1289
|
+
unpackHmId,
|
|
1290
|
+
codePointLength,
|
|
1291
|
+
isSurrogate
|
|
1044
1292
|
};
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import type
|
|
2
|
+
import { type HMPrepareDocumentChangeInput, type HMRequest, type HMSigner } from './hm-types';
|
|
3
3
|
/**
|
|
4
4
|
* Deserializes a URL query string using a Zod schema.
|
|
5
5
|
* If the query contains only a __value key, returns the primitive value directly.
|
package/dist/comment.d.ts
CHANGED
|
@@ -40,4 +40,9 @@ export type DeleteCommentInput = {
|
|
|
40
40
|
visibility?: 'Private' | '';
|
|
41
41
|
};
|
|
42
42
|
export declare function deleteComment(input: DeleteCommentInput, signer: HMSigner): Promise<HMPublishBlobsInput>;
|
|
43
|
+
/**
|
|
44
|
+
* Compute the record ID ("authority/tsid") from raw CBOR-encoded comment blob bytes.
|
|
45
|
+
* The TSID is a 10-byte base58btc value: 6 bytes ms timestamp + 4 bytes SHA256 prefix.
|
|
46
|
+
*/
|
|
47
|
+
export declare function commentRecordIdFromBlob(blobData: Uint8Array): Promise<string>;
|
|
43
48
|
export {};
|
package/dist/contact.d.ts
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
import type { HMPublishBlobsInput, HMSigner } from './hm-types';
|
|
2
|
+
export type ContactSubscribe = {
|
|
3
|
+
site?: boolean;
|
|
4
|
+
profile?: boolean;
|
|
5
|
+
};
|
|
2
6
|
export type CreateContactInput = {
|
|
3
7
|
/** The subject account UID (base58btc-encoded principal) */
|
|
4
8
|
subjectUid: string;
|
|
9
|
+
/** The account UID (base58btc-encoded principal) */
|
|
10
|
+
accountUid?: string;
|
|
5
11
|
/** The display name for the contact */
|
|
6
|
-
name
|
|
12
|
+
name?: string;
|
|
13
|
+
/** The subscribe information for the contact */
|
|
14
|
+
subscribe?: ContactSubscribe;
|
|
7
15
|
};
|
|
8
16
|
export type UpdateContactInput = {
|
|
9
17
|
/** The contact record ID in format "authority/tsid" */
|
|
10
18
|
contactId: string;
|
|
11
19
|
/** The subject account UID */
|
|
12
20
|
subjectUid: string;
|
|
21
|
+
/** The account UID (base58btc-encoded principal) */
|
|
22
|
+
accountUid?: string;
|
|
13
23
|
/** The updated display name */
|
|
14
|
-
name
|
|
24
|
+
name?: string;
|
|
25
|
+
/** The subscribe information for the contact */
|
|
26
|
+
subscribe?: ContactSubscribe;
|
|
15
27
|
};
|
|
16
28
|
export type DeleteContactInput = {
|
|
17
29
|
/** The contact record ID in format "authority/tsid" */
|
|
18
30
|
contactId: string;
|
|
31
|
+
/** The account UID (base58btc-encoded principal) */
|
|
32
|
+
accountUid?: string;
|
|
19
33
|
};
|
|
20
34
|
export type CreateContactResult = HMPublishBlobsInput & {
|
|
21
35
|
/** The record ID in format "authority/tsid" */
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves document state (genesis, heads, depth) from the ListChanges API.
|
|
3
|
+
*
|
|
4
|
+
* Depth is needed to construct valid Change blobs but is not directly
|
|
5
|
+
* exposed by the read API. We compute it by walking the change DAG:
|
|
6
|
+
* genesis has depth 0, each subsequent change has depth = max(dep depths) + 1.
|
|
7
|
+
*/
|
|
8
|
+
import type { SeedClient } from './client';
|
|
9
|
+
/** The resolved state of a document's change DAG. */
|
|
10
|
+
export type DocumentState = {
|
|
11
|
+
/** CID of the genesis change blob. */
|
|
12
|
+
genesis: string;
|
|
13
|
+
/** CIDs of the current head changes (not depended on by any other change). */
|
|
14
|
+
heads: string[];
|
|
15
|
+
/** Maximum depth among head changes. */
|
|
16
|
+
headDepth: number;
|
|
17
|
+
/** Dot-separated head CIDs (version string). */
|
|
18
|
+
version: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Resolves the current document state including head depth.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveDocumentState(client: SeedClient, targetId: string): Promise<DocumentState>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared IPFS file chunking utilities.
|
|
3
|
+
*
|
|
4
|
+
* Chunks binary data into UnixFS IPFS blocks using a MemoryBlockstore.
|
|
5
|
+
* Used by both the CLI (file:// link resolution) and the web app
|
|
6
|
+
* (comment attachment uploads) so the logic is not duplicated.
|
|
7
|
+
*/
|
|
8
|
+
import type { HMBlockNode } from './hm-types';
|
|
9
|
+
export type CollectedBlob = {
|
|
10
|
+
cid: string;
|
|
11
|
+
data: Uint8Array;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Chunk a single piece of binary data into UnixFS IPFS blocks.
|
|
15
|
+
*
|
|
16
|
+
* Returns the root CID and all constituent IPFS blobs (DAG blocks)
|
|
17
|
+
* that should be published alongside the document/comment.
|
|
18
|
+
*/
|
|
19
|
+
export declare function fileToIpfsBlobs(data: Uint8Array): Promise<{
|
|
20
|
+
cid: string;
|
|
21
|
+
blobs: CollectedBlob[];
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Chunk multiple binary attachments into IPFS blocks using a shared blockstore.
|
|
25
|
+
*
|
|
26
|
+
* Returns the root CIDs (one per input) and all collected IPFS blobs.
|
|
27
|
+
* This is the multi-file equivalent of `fileToIpfsBlobs`, suitable for
|
|
28
|
+
* comment editors that upload several images at once.
|
|
29
|
+
*/
|
|
30
|
+
export declare function filesToIpfsBlobs(binaries: Uint8Array[]): Promise<{
|
|
31
|
+
resultCIDs: string[];
|
|
32
|
+
blobs: CollectedBlob[];
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Resolve all file:// links in a block tree.
|
|
36
|
+
*
|
|
37
|
+
* Walks the tree, finds blocks whose `link` field starts with `file://`,
|
|
38
|
+
* reads the data via the provided `readFile` callback, chunks with UnixFS,
|
|
39
|
+
* and replaces the link with `ipfs://ROOT_CID`.
|
|
40
|
+
*
|
|
41
|
+
* The `readFile` callback allows this to work in both Node.js (fs.readFileSync)
|
|
42
|
+
* and browser environments without importing `fs` directly.
|
|
43
|
+
*
|
|
44
|
+
* @returns The modified block tree and all collected IPFS blobs.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveFileLinksInBlocks(nodes: HMBlockNode[], readFile: (path: string) => Uint8Array | Promise<Uint8Array>): Promise<{
|
|
47
|
+
nodes: HMBlockNode[];
|
|
48
|
+
blobs: CollectedBlob[];
|
|
49
|
+
}>;
|
|
50
|
+
/**
|
|
51
|
+
* Check whether any block in the tree has a file:// link.
|
|
52
|
+
*/
|
|
53
|
+
export declare function hasFileLinks(nodes: HMBlockNode[]): boolean;
|